package com.mutouren.common.orm;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

public class IbatisHelper {

	private static <T> T executeWithNewSession(IbatisCallback<T> action) {
		IbatisTrans trans = new IbatisTrans();
		try{
			trans.begin();
			T result = action.doInIbatis(trans.getSession());			
						
			trans.commit();
			return result;
		} catch(RuntimeException ex) {
			trans.rollback();
			throw ex;
		} finally {
			trans.close();
		}
	}
	
	private static <T> T execute(IbatisCallback<T> action, IbatisTrans trans) {
		if(trans == null) {
			return executeWithNewSession(action);
		} else {			
			return action.doInIbatis(trans.getSession());
		}
	}
	
	public static <T> T selectOne(final String statement, final Object parameter) {
		return selectOne(statement, parameter, null);
	}
	public static <T> T selectOne(final String statement, final Object parameter, IbatisTrans trans) {
		return execute(new IbatisCallback<T>() {
			@Override
			public T doInIbatis(SqlSession session) {
				return session.selectOne(statement, parameter);		
			}
		}, trans);
	}
	
	public static <T> List<T> select(final String statement, final Object parameter) {
		return select(statement, parameter, null);
	}
	public static <T> List<T> select(final String statement, final Object parameter, IbatisTrans trans) {
		return execute(new IbatisCallback<List<T>>() {
			@Override
			public List<T> doInIbatis(SqlSession session) {
				return session.selectList(statement, parameter);		
			}
		}, trans);
	}
	
	public static void save(final String statement, final Object parameter) {
		save(statement, parameter, null);
	}
	public static void save(final String statement, final Object parameter, IbatisTrans trans) {
		execute(new IbatisCallback<Object>() {
			@Override
			public Object doInIbatis(SqlSession session) {
				int result = session.insert(statement, parameter);
				if(result == 0) {
					throw new RuntimeException("Ibatis save fail, statement: " + statement);
				}
				return null;				
			}
		}, trans);
	}
	
	public static int update(final String statement, final Object parameter) {
		return update(statement, parameter, null);
	}
	public static int update(final String statement, final Object parameter, IbatisTrans trans) {
		return execute(new IbatisCallback<Integer>() {
			@Override
			public Integer doInIbatis(SqlSession session) {
				return session.update(statement, parameter);				
			}
		}, trans);
	}
	
	public static int delete(final String statement, final Object parameter) {
		return delete(statement, parameter, null);
	}
	public static int delete(final String statement, final Object parameter, IbatisTrans trans) {
		return execute(new IbatisCallback<Integer>() {
			@Override
			public Integer doInIbatis(SqlSession session) {
				return session.delete(statement, parameter);
			}
		}, trans);
	}
		
}
